/*
 * @Author: intellectual-seeker 3336339701@qq.com
 * @Date: 2025-09-03 09:52:18
 * @LastEditors: intellectual-seeker 3336339701@qq.com
 * @LastEditTime: 2025-09-03 12:00:51
 * @FilePath: /code/lesson33/consumer_productor/Main.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "Thread.hpp"
#include "BlockQueue.hpp"
#include <vector>
using namespace ThreadModule;
#include <unistd.h>
#include <cstdlib>
#include <ctime>
#include "Task.hpp"

using blockqueue_t = BlockQueue<Task>;

void ProductorRun(blockqueue_t& bq)
{
    while(true)
    {
        sleep(1);//生产慢
        Task t(rand() % 10, rand() % 10);
        bq.Enqueue(t);
        t.toDebugQuestion();
    }
}

void ConsumerRun(blockqueue_t& bq)
{
    Task t;
    while(true)
    {
        //sleep(1);//消费慢
        bq.Pop(&t);
        t.toDebugAnswer();
    }
}

void StartComm(vector<Thread<blockqueue_t> >& threads, blockqueue_t& bq, func_t<blockqueue_t> func, int num, string who)
{
    for(int i = 0; i < num; i++)
    {
        string name = who + '-' + to_string(i + 1);
        threads.emplace_back(func, bq, name);//只创建了thread类，未运行
        threads.back().start();
        cout << name << " create success..." << endl;
    }
}

void StartProductor(vector<Thread<blockqueue_t> >& threads, blockqueue_t& bq, int num)
{
    StartComm(threads, bq, ProductorRun, num, "Productor");
}

void StartConsumer(vector<Thread<blockqueue_t> >& threads, blockqueue_t& bq, int num)
{
    StartComm(threads, bq, ConsumerRun, num, "Consumer");
}

void WaitAllThreads(vector<Thread<blockqueue_t> >& threads)
{
    for(auto& thread : threads)
    {
        thread.join();
    }
}

//单生产，单消费
int main()
{
    srand((size_t)time(nullptr));

    vector<Thread<blockqueue_t> > threads; //存指针还是存对象
    blockqueue_t bq(5);//创建阻塞队列容量为5
    StartProductor(threads, bq, 3);
    StartConsumer(threads, bq, 5);
    WaitAllThreads(threads);

    return 0;
}